
/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2022-12-07     Wangjiangbo       the first version
 */
#include "app_io.h"
#include <App/app_comm.h>
#include <BSP/bsp_uart6.h>

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

#define bool
#include <qled.h>
#undef bool

#ifdef __cplusplus
}
#endif /* __cplusplus */



#define DBG_TAG "io"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

const uint32_t rgb_pin[][3] {
    {
        GET_PIN(A, 4), GET_PIN(A, 5), GET_PIN(A, 6)
    },

    {
        GET_PIN(B, 13), GET_PIN(B, 14), GET_PIN(B, 15)
    },
};

const uint32_t hall_pin[3] = {
    GET_PIN(C, 13), GET_PIN(C, 14), GET_PIN(C, 15)
};

const uint32_t key_pin[9] = {
    GET_PIN(A, 7), GET_PIN(C, 4), GET_PIN(C, 5), GET_PIN(B, 0),
    GET_PIN(B, 1), GET_PIN(B, 2), GET_PIN(B, 10), GET_PIN(B, 11), GET_PIN(B, 12)
};

const uint32_t sense_pin[4] = {
    GET_PIN(C, 8), GET_PIN(C, 9),
    GET_PIN(A, 8), GET_PIN(A, 9)
};

const uint32_t fan_pin = GET_PIN(B, 4);

static bitfilter_t key_filter[9];
static bitfilter_t hall_filter[3];
static bitfilter_t sense_filter[4];

iomap gpio_map;

static void input_fulsh(iomap* map)
{
    int bitval = 0;

    for(uint32_t i = 0 ; i < sizeof(hall_pin) / sizeof(uint32_t); i++)
    {
        bitval = rt_pin_read(hall_pin[i]);
        mod_bitfilter_poll(bitval, hall_filter + i);

        map->hall_st[i] = mod_bitfilter_state(hall_filter + i);
    }

    for(uint32_t i = 0 ; i < sizeof(key_pin) / sizeof(uint32_t); i++)
    {
        bitval = rt_pin_read(key_pin[i]);
        mod_bitfilter_poll(bitval, key_filter + i);

        map->key_st[i] = mod_bitfilter_state(key_filter + i);
    }

    for(uint32_t i = 0 ; i < sizeof(sense_pin) / sizeof(uint32_t); i++)
    {
        bitval = rt_pin_read(sense_pin[i]);
        mod_bitfilter_poll(bitval, sense_filter + i);

        map->sense_st[i] = mod_bitfilter_state(sense_filter + i);
    }

}

static void output_fulsh(iomap* map)
{
    for(int i = 0; i < 2 ; i++)
    {
        if(map->rgb[i].freq == 0)
        {
            if(map->rgb[i].style & 0x04)
                qled_set_on(rgb_pin[i][0]);
            else
                qled_set_off(rgb_pin[i][0]);

            if(map->rgb[i].style & 0x02)
                qled_set_on(rgb_pin[i][1]);
            else
                qled_set_off(rgb_pin[i][1]);

            if(map->rgb[i].style & 0x01)
                qled_set_on(rgb_pin[i][2]);
            else
                qled_set_off(rgb_pin[i][2]);
        }
        else
        {
            if((map->rgb[i].style_backup != map->rgb[i].style)||(map->rgb[i].freq_backup != map->rgb[i].freq))
            {
                map->rgb[i].style_backup = map->rgb[i].style;
                map->rgb[i].freq_backup = map->rgb[i].freq;
                int time = 1000.0f / map->rgb[i].freq / 2;

                if(map->rgb[i].style & 0x04)
                    qled_set_blink(rgb_pin[i][0], time, time);
                else
                    qled_set_off(rgb_pin[i][0]);

                if(map->rgb[i].style & 0x02)
                    qled_set_blink(rgb_pin[i][1], time, time);
                else
                    qled_set_off(rgb_pin[i][1]);

                if(map->rgb[i].style & 0x01)
                    qled_set_blink(rgb_pin[i][2], time, time);
                else
                    qled_set_off(rgb_pin[i][2]);
            }
        }
    }

    rt_pin_write(fan_pin, map->fan_pow);
}

static void app_io_thread_entry(void* param)
{
    while(1)
    {
        iomap* map = (iomap*)param;

        input_fulsh(map);
        output_fulsh(map);
        rt_thread_mdelay(10);
    }
}

void app_io_init(iomap* map)
{
    uint32_t i;

    //变量初始化
    map->fan_pow = 1;
    map->rgb[0].style = 0;
    map->rgb[1].style = 0;
    map->rgb[0].freq = 0;
    map->rgb[1].freq = 0;


    //初始化滤波结构体
    for(i = 0 ; i < sizeof(hall_filter) / sizeof(bitfilter_t); i++)
        mod_bitfilter_init(hall_filter + i, 5, 5);

    for(i = 0 ; i < sizeof(key_filter) / sizeof(bitfilter_t); i++)
        mod_bitfilter_init(key_filter + i, 5, 5);

    for(i = 0 ; i < sizeof(sense_filter) / sizeof(bitfilter_t); i++)
        mod_bitfilter_init(sense_filter + i, 5, 5);


    //输入引脚初始化
    for(i = 0 ; i < sizeof(hall_pin) / sizeof(uint32_t); i++)
        rt_pin_mode(hall_pin[i], PIN_MODE_INPUT);

    for(i = 0 ; i < sizeof(key_pin) / sizeof(uint32_t); i++)
        rt_pin_mode(key_pin[i], PIN_MODE_INPUT);

    for(i = 0 ; i < sizeof(sense_pin) / sizeof(uint32_t); i++)
        rt_pin_mode(sense_pin[i], PIN_MODE_INPUT);

    for(int i = 0; i < 30; i++)
    {
        input_fulsh(map);
        rt_thread_mdelay(5);
    }

//    output_fulsh(map);

    //输出引脚初始化

    for(i = 0 ; i < sizeof(rgb_pin) / sizeof(uint32_t); i++)
    {
        uint32_t* p= (uint32_t*)rgb_pin;
        rt_pin_mode((rt_base_t)p[i], PIN_MODE_OUTPUT);
        qled_add((int)p[i], 1);
        qled_set_off((int)p[i]);
    }


    rt_pin_mode(fan_pin, PIN_MODE_OUTPUT);

    output_fulsh(map);

    rt_thread_t thread = rt_thread_create("io", app_io_thread_entry, map,
                                  1024, 15, 20);

    if (thread == RT_NULL)
    {
        LOG_D("io_thread error");
    }

    rt_thread_startup(thread);

}

static int dbg_io_info(int argc, char *argv[])
{
    uint32_t i;
    uint8_t temp=atoi(argv[1]);
    for(i = 0 ; i < sizeof(gpio_map.hall_st) / sizeof(uint8_t); i++)
        LOG_I("hall_st[%d] = %d", i, gpio_map.hall_st[i]);

    for(i = 0 ; i < sizeof(gpio_map.key_st) / sizeof(uint8_t); i++)
        LOG_I("key_st[%d] = %d", i, gpio_map.key_st[i]);

    for(i = 0 ; i < sizeof(gpio_map.sense_st) / sizeof(uint8_t); i++)
        LOG_I("sense_st[%d] = %d", i, gpio_map.sense_st[i]);

//    LOG_I("fan_pow = %d", gpio_map.fan_pow);
    switch(temp)
    {
        case 1:
            for(int i = 0; i < 2 ; i++)
            {
                qled_set_blink(rgb_pin[i][0], 1000, 1000);
                qled_set_off(rgb_pin[i][1]);
                qled_set_off(rgb_pin[i][2]);
            }
            break;
        case 2:
            for(int i = 0; i < 2 ; i++)
            {
                qled_set_off(rgb_pin[i][0]);
                qled_set_blink(rgb_pin[i][1], 1000, 1000);
                qled_set_off(rgb_pin[i][2]);
            }
            break;
        case 3:
            for(int i = 0; i < 2 ; i++)
            {
                qled_set_off(rgb_pin[i][0]);
                qled_set_off(rgb_pin[i][1]);
                qled_set_blink(rgb_pin[i][2], 1000, 1000);
            }
            break;
        default:break;
    }
    return RT_EOK;
}
MSH_CMD_EXPORT(dbg_io_info, 获取io信息);


